package GMDPRE

import (
	"fmt"
	"time"
)

func TestSm4EnAndDeStd() {
	var mBytes = []uint8{0x1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}
	var keyBytes = []uint8{0x1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}
	var cBytes = Sm4Encrypt(mBytes, len(mBytes), keyBytes)
	var m = Sm4Decrypt(cBytes, len(cBytes), keyBytes)
	fmt.Print("Test Sm4 Sm4Encrypt and Sm4Decrypt standard: ")
	fmt.Println(BytesEqual(mBytes, m[:len(mBytes)], len(mBytes)) == 1)
}

func TestSm4EnAndDeRnd() {
	var keyBytes = []uint8{0x1, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}

	for i := 0; i < 1000; i++ {
		var mBytes = GetRandomBytes(sysRand.Int() & 0xfff)
		var cBytes = Sm4Encrypt(mBytes, len(mBytes), keyBytes)
		var m = Sm4Decrypt(cBytes, len(cBytes), keyBytes)

		if BytesEqual(mBytes, m[:len(mBytes)], len(mBytes)) != 1 {
			fmt.Println("Test Sm4 Sm4Encrypt and Sm4Decrypt random data: Failed!!!!!!!!!!!!!!!!!")
			return
		}
	}

	fmt.Println("Test Sm4 Sm4Encrypt and Sm4Decrypt random data: Success")
}

func TestSm4() {
	fmt.Println("+------------------------------------------------------------------------------+")
	fmt.Println("+---    Test module  --->  sm4")
	TestSm4EnAndDeStd()
	TestSm4EnAndDeRnd()
	fmt.Println("+------------------------------------------------------------------------------+")
}

func benchSm4Encrypt() {
	var cost int64 = 0

	var i, j int
	var start time.Time
	key := GetRandomBytes(Sm4BlockSize)
	for i = 0; i < 100; i++ {
		m := GetRandomBytes(1024)
		start = time.Now()
		for j = 0; j < 10; j++ {
			Sm4Encrypt(m, 1024, key)
		}
		// 单位：微秒
		cost += time.Since(start).Microseconds()
	}
	fmt.Printf("bench Sm4 Encrypt: %.2f us\n", float64(cost)/1000.0)
}

func benchSm4Decrypt() {
	var cost int64 = 0

	var i, j int
	var start time.Time
	key := GetRandomBytes(Sm4BlockSize)
	for i = 0; i < 100; i++ {
		m := GetRandomBytes(1024)
		start = time.Now()
		for j = 0; j < 10; j++ {
			Sm4Decrypt(m, 1024, key)
		}
		// 单位：微秒
		cost += time.Since(start).Microseconds()
	}
	fmt.Printf("bench Sm4 Decrypt: %.2f us\n", float64(cost)/1000.0)
}

func BenchSm4() {
	fmt.Println("+------------------------------------------------------------------------------+")
	fmt.Println("+---    Bench module  --->  sm4")
	benchSm4Encrypt()
	benchSm4Decrypt()
	fmt.Println("+------------------------------------------------------------------------------+")
}
